﻿//
//  Copyright (c) 2011 Extreme: Paweł Huryn (lead), Jakub Domański
//

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace Extreme.SPFramework.Configuration
{
    /// <summary>
    /// Entity mapping factory
    /// </summary>
    public class EntityMappingFactory<T>
    {
        /// <summary>
        /// SP list name
        /// </summary>
        public string SharepointListName { get; private set; }

        /// <summary>
        /// Properties mapping
        /// </summary>
        public Dictionary<string, PropertyMapping> PropertiesMapping { get; private set; }

        /// <summary>
        /// Site url
        /// </summary>
        public string SiteUrl { get; private set; }

        /// <summary>
        /// Web name
        /// </summary>
        public string WebName { get; private set; }

        /// <summary>
        /// Creates new entity table mapping creator
        /// </summary>
        /// <param name="name">Data table name</param>
        public EntityMappingFactory(string name)
        {
            SharepointListName = name;
            PropertiesMapping = new Dictionary<string, PropertyMapping>();
        }

        /// <summary>
        /// Creates new entity table mapping creator
        /// </summary>
        /// <param name="name">Data table name</param>
        /// <param name="siteUrl">Site url</param>
        /// <param name="webName">Web Name</param>
        public EntityMappingFactory(string name, string siteUrl, string webName)
        {
            SharepointListName = name;
            SiteUrl = siteUrl;
            WebName = webName;
            PropertiesMapping = new Dictionary<string, PropertyMapping>();
        }

        /// <summary>
        /// Creates Entity Mapping
        /// </summary>
        /// <returns></returns>
        public EntityMapping Create()
        {
            if (string.IsNullOrEmpty(SiteUrl))
                return new EntityMapping(typeof(T), SharepointListName, PropertiesMapping);
            else
                return new EntityMapping(typeof(T), SharepointListName, PropertiesMapping, SiteUrl, WebName);
        }

        /// <summary>
        /// Adds two-way mapping
        /// </summary>
        /// <param name="propertyName">Property name</param>
        /// <param name="columnName">Column name</param>
        public void AddMapping(string propertyName, string columnName)
        {
            AddMapping(propertyName, columnName, false);
        }

        /// <summary>
        /// Adds mapping
        /// </summary>
        /// <param name="propertyName">Property name</param>
        /// <param name="columnName">Column name</param>
        /// <param name="readOnly">Indicates if read-only or two-way mapping</param>
        public void AddMapping(string propertyName, string columnName, bool readOnly)
        {
            PropertiesMapping.Add(propertyName, new PropertyMapping(columnName, readOnly));
        }

        /// <summary>
        /// Adds two-way mapping
        /// </summary>
        /// <typeparam name="T">Type of entity</typeparam>
        /// <param name="property">Property of entity expression</param>
        /// <param name="columnName">Sharepoint column name</param>
        public void AddMapping(Expression<Func<T, object>> property, string columnName)
        {
            AddMapping(property, columnName, false);
        }

        /// <summary>
        /// Adds mapping
        /// </summary>
        /// <typeparam name="T">Type of entity</typeparam>
        /// <param name="property">Property of entity expression</param>
        /// <param name="columnName">Sharepoint column name</param>
        /// <param name="readOnly">Indicates if read-only or two-way mapping</param>
        public void AddMapping(Expression<Func<T, object>> property, string columnName, bool readOnly)
        {
            var propertyName = PropertyName.For<T>(property);
            PropertiesMapping.Add(propertyName, new PropertyMapping(columnName, readOnly));
        }
    }
}
